using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using Gko.Utils;

namespace Gko.Wpf.Mvvm
{
	public class SynchronizedObservableCollection<T> : ObservableCollection<T>
	{
		private readonly SynchronizationContext context;
		private readonly ReaderWriterLockSlim sync = new ReaderWriterLockSlim();
		public SynchronizedObservableCollection(SynchronizationContext context)
		{
			this.context = context;
		}

		public SynchronizedObservableCollection(SynchronizationContext context, List<T> list)
			: base(list)
		{
			this.context = context;
		}

		public SynchronizedObservableCollection(SynchronizationContext context, IEnumerable<T> collection)
			: base(collection)
		{
			this.context = context;
		}

		public SynchronizationContext Context
		{
			get
			{
				return this.context;
			}
		}

		protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
		{
			this.context.Invoke(base.OnCollectionChanged, e);
		}

		protected override void OnPropertyChanged(PropertyChangedEventArgs e)
		{
			this.context.Invoke(base.OnPropertyChanged, e);
		}

		protected override void ClearItems()
		{
			using (this.sync.Write()) {
				base.ClearItems();
			}
		}

		protected override void InsertItem(int index, T item)
		{
			using (this.sync.Write()) {
				base.InsertItem(index, item);
			}
		}

		protected override void MoveItem(int oldIndex, int newIndex)
		{
			using (this.sync.Write()) {
				base.MoveItem(oldIndex, newIndex);
			}
		}

		protected override void RemoveItem(int index)
		{
			using (this.sync.Write()) {
				base.RemoveItem(index);
			}
		}

		protected override void SetItem(int index, T item)
		{
			using (this.sync.Write()) {
				base.SetItem(index, item);
			}
		}
	}
}